import logging
import os
import re
from urllib.parse import unquote
from image_reference import ImageReference


class MarkdownNote:
    image_references: list[ImageReference]

    def __init__(self, absolute_path: str):
        """

        :param absolute_path: Markdown 文件的完整路径。
        """
        self.abs_path = absolute_path
        self.filename = os.path.basename(absolute_path).split('.')[0]
        # ImageReference 对象列表，用于存储图片引用信息。
        self.image_references = []

    def __str__(self):
        return f"MarkdownNote(filename={self.filename}, image_references={self.image_references})"

    def extract_image_references(self, images_dir: str):
        rel_paths = self.extract_image_reference_paths()
        # 遍历所有图片引用
        for rel_path in rel_paths:
            image_name = os.path.basename(rel_path)
            abs_path = os.path.join(images_dir, image_name)
            abs_path = os.path.normpath(unquote(abs_path))

            if not os.path.exists(abs_path):
                logging.warning(f"图片文件 '{abs_path}' 不存在，跳过处理")
                continue

            image_ref = ImageReference(abs_path, rel_path, self.filename)
            self.image_references.append(image_ref)

    def extract_image_reference_paths(self):
        """
        提取引用的图片的相对地址（相对于 markdown 文件的地址）

        """
        image_reference_paths = []

        # 匹配本地图片引用（排除以 http(s) 开头的 URL）
        image_pattern = re.compile(r'!\[.*?]\((?!https?://)(.+?\.(?:png|jpe?g|gif|svg))\)')

        try:
            with open(self.abs_path, 'r', encoding='utf-8') as file:
                content = file.read()
                matches = image_pattern.findall(content)

                if matches:
                    image_reference_paths.extend(matches)
        except Exception as e:
            logging.error(f"读取文件时出错: {self.abs_path}, 错误: {e}")

        # 清除重复的引用
        if len(image_reference_paths) > 0:
            image_reference_paths = list(set(image_reference_paths))
            logging.info(f"图片引用列表：{image_reference_paths}")

        return image_reference_paths

    def update_image_references(self):
        """
        更新 Markdown 文件的图片引用

        """
        try:
            # 读取 Markdown 文件内容
            with open(self.abs_path, 'r', encoding='utf-8') as file:
                content = file.read()

            # 遍历图片引用列表
            for image_ref in self.image_references:
                content = self.update_image_reference(content, image_ref)

            # 将更新后的内容写入临时文件，避免原文件损坏
            temp_file_path = self.abs_path + '.tmp'
            with open(temp_file_path, 'w', encoding='utf-8') as file:
                file.write(content)

            # 替换原文件
            os.replace(temp_file_path, self.abs_path)

        except Exception as e:
            logging.error(f"处理 Markdown 文件时出错：{self.abs_path}, 错误：{e}")
            raise  # 可选：是否重新抛出异常取决于调用方需求

    def update_image_reference(self, content: str, image_ref):
        """
        更新单个图片引用。

        :param content: 当前 Markdown 文件的内容
        :param image_ref: ImageReference 对象，包含新的图片引用信息
        :return: 更新后的内容
        """
        old_rel_path = image_ref.rel_path

        # 更新图片引用（可能修改 image_ref 的属性）
        image_ref.update()

        # 构建 Markdown 图片引用正则表达式，精确匹配旧引用
        pattern = re.compile(r'!\[.*]\(' + re.escape(old_rel_path) + r'\)')
        replacement = f"![{image_ref.name}]({image_ref.rel_path})"

        # 替换 Markdown 内容中的图片引用
        if pattern.search(content):
            updated_content = pattern.sub(replacement, content)
            logging.info(f"[文件: {self.filename}] 已更新引用：{old_rel_path} -> {image_ref.rel_path}")
            return updated_content
        else:
            logging.warning(f"[文件: {self.filename}] 未找到匹配的图片引用：{old_rel_path}")
            return content
